package com.godme.concurrent.juc;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class LockTest {

    static class Queue{
        private final ReentrantLock lock = new ReentrantLock();
        private final Condition readCondition = lock.newCondition();
        private final Condition writeCondition = lock.newCondition();
        private int value = -1;
        private boolean readable = false;


        public void put(int a) throws InterruptedException {
            lock.lock();
           if(readable){
               writeCondition.await();
           }
           this.value = a;
           readable = true;
           readCondition.signal();
           lock.unlock();
        }


        public synchronized int get() throws InterruptedException {
            lock.lock();
            if(!readable){
                readCondition.await();
            }
            try{
                return value;
            }finally {
                writeCondition.signal();
                readable = false;
                lock.unlock();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(3);
        Queue queue = new Queue();
        new Thread(()->{
            try{
                while (true){
                    System.err.println(queue.get());
                }
            }catch (Exception ignore){
                latch.countDown();
            }
        }).start();
        new Thread(()->{
            try{
                for (int i = 0; i < 10; i++) {
                    queue.put(i);
                }
            }catch (Exception ignore){
                ignore.printStackTrace();
                latch.countDown();
            }
        }).start();
        new Thread(()->{
            try{
                BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
                String line;
                while((line = reader.readLine()) != null){
                    queue.put(Integer.parseInt(line));
                }
            }catch (Exception ignore){
                latch.countDown();
            }
        }).start();
        latch.await();
    }
}
